using System;
using System.Reflection;

namespace Foundry.Engine
{
	public static class Extensions
	{
		public static bool ImplementsAttribute<T>(this Type t)
			where T : Attribute
		{
			var obj = t.GetCustomAttributes(typeof(T), true);
			return obj.Length > 0;
		}
		public static T GetCustomAttribute<T>(this Type t)
			where T : Attribute
		{
			var obj = t.GetCustomAttributes(typeof(T), true);
			if(obj.Length > 0)
				return obj[0] as T;
			else
				return null;
		}
		
		
		
		public static bool ImplementsAttribute<T>(this MemberInfo t)
			where T : Attribute
		{
			var obj = t.GetCustomAttributes(typeof(T), true);
			return obj.Length > 0;
		}
		public static T GetCustomAttribute<T>(this MemberInfo t)
			where T : Attribute
		{
			var obj = t.GetCustomAttributes(typeof(T), true);
			if(obj.Length > 0)
				return obj[0] as T;
			else
				return null;
		}
		
		public static OpenTK.Quaternion ToQuaternion(this OpenTK.Matrix4 mat)
		{
			var quat = OpenTK.Quaternion.Identity;
			quat.W = (float)Math.Sqrt( Math.Max( 0, 1 + mat.M11 + mat.M22 + mat.M33 ) ) * .5f;
			quat.X = (float)Math.Sqrt( Math.Max( 0, 1 + mat.M11 - mat.M22 - mat.M33 ) ) * .5f;
			quat.Y = (float)Math.Sqrt( Math.Max( 0, 1 - mat.M11 + mat.M22 - mat.M33 ) ) * .5f;
			quat.Z = (float)Math.Sqrt( Math.Max( 0, 1 - mat.M11 - mat.M22 + mat.M33 ) ) * .5f;
			
			
			quat.X = Math.Abs(quat.X) * Math.Sign( mat.M32 - mat.M23 );
			quat.Y = Math.Abs(quat.Y) * Math.Sign( mat.M13 - mat.M31 );
			quat.Z = Math.Abs(quat.Z) * Math.Sign( mat.M21 - mat.M12 );
					
					return quat;
		}

	}
}

